//https://www.shadertoy.com/view/Xs33Df

precision lowp float;
varying vec2 vTextureCoord;
uniform float iTime;
uniform vec2 iResolution;
uniform vec2 iPos;
uniform sampler2D uSampler;		
int iChannel0 = 0;		

//imgfile=shader/noise.png

// create by JiepengTan 2018-04-18  email: jiepengtan@gmail.com

vec3 lightDir = normalize( vec3(0.5,0.6,0.) );
const mat2 m2 = mat2( 0.60, -0.80, 0.80, 0.60 );

vec4 textureLodEx2(int i, vec2 p,  float lod){
    float x = fract((p.x));
    float y = fract((p.y));

    vec4 v = texture2D(uSampler,vec2(x,y));
    // return v;
    if (v.a == 0.0){
        return v;
    }
    vec4 d = v / v.a;
    return vec4(clamp(d.x,0.0,1.0),clamp(d.y,0.0,1.0),clamp(d.z,0.0,1.0),v.a);
}

vec4 textureLodEx(int i, vec2 p,  float lod){
    float x = fract(abs(p.x));
    float y = fract(abs(p.y));
    //float x = fract((p.x));
    //float y = fract((p.y));
    //return textureLod(i,vec2(x,y),lod);
    vec4 v = texture2D(uSampler,vec2(x,y));
    // return v;
    if (v.a == 0.0){
        return v;
    }
    vec4 d = v / v.a;
    return d;
}

vec3 Cloud(vec3 bgCol,vec3 ro,vec3 rd,vec3 cloudCol,float spd)
{
    vec3 col = bgCol;
    float t = iTime * 0.15* spd;
    vec2 sc = ro.xz + rd.xz*((3.)*40000.0-ro.y)/rd.y;
    vec2 p = 0.00002*sc;
    float f = 0.0;
  	float s = 0.5;
  	float sum =0.;
  	for(int i=0;i<5;i++){
    	p += t;t *=1.5;
    	f += s*textureLodEx( iChannel0, p/256.0, 0.0).x; p = m2*p*2.02;
    	sum+= s;s*=0.6;
  	}
    float val = f/sum; 
    col = mix( col, cloudCol, 0.5*smoothstep(0.5,0.8,val) );
    return col;
}

vec3 RayMarchCloud(vec3 ro,vec3 rd){
    vec3 col = vec3(0.0,0.0,0.0);  
    float sundot = clamp(dot(rd,lightDir),0.0,1.0);
    
     // sky      
    col = vec3(0.2,0.5,0.85)*1.1 - rd.y*rd.y*0.5;
    col = mix( col, 0.85*vec3(0.7,0.75,0.85), pow( 1.0-max(rd.y,0.0), 4.0 ) );
    // sun
    col += 0.25*vec3(1.0,0.7,0.4)*pow( sundot,5.0 );
    col += 0.25*vec3(1.0,0.8,0.6)*pow( sundot,64.0 );
    col += 0.4*vec3(1.0,0.8,0.6)*pow( sundot,512.0 );
    // clouds
    col = Cloud(col,ro,rd,vec3(1.0,0.95,1.0),1.);
            // .
    col = mix( col, 0.68*vec3(0.4,0.65,1.0), pow( 1.0-max(rd.y,0.0), 16.0 ) );
    return col;
}



#define mouse (iMouse.xy / iResolution.xy)
vec3 InitCam(in vec2 fragCoord ){
    //float time = iTime;
    //vec2 uv = fragCoord.xy / iResolution.xy;
  
  	vec2 p = fragCoord.xy/iResolution.xy-0.5;
    //vec2 q = fragCoord.xy/iResolution.xy;
	p.x*=iResolution.x/iResolution.y;
    vec2 iMouse = iPos;
    vec2 mo = iMouse.xy / iResolution.xy-.5;
    mo = (mo==vec2(-.5))?mo=vec2(-0,0.4):mo;
	mo.x *= iResolution.x/iResolution.y * 3.14159;
	

    mo.x += smoothstep(0.6,1.,0.5+0.5)-1.5;
    vec3 eyedir = normalize(vec3(cos(mo.x),mo.y*2.-0.2+sin(1.57)*0.1,sin(mo.x)));
    vec3 rightdir = normalize(vec3(cos(mo.x+1.5708),0.,sin(mo.x+1.5708)));
    vec3 updir = normalize(cross(rightdir,eyedir));
	vec3 rd=normalize((p.x*rightdir+p.y*updir)*1.+eyedir);
	return rd;
}

vec4 mainImage( vec2 uvIn ) {
	uvIn.y = 1.0 - uvIn.y;
    vec2 fragCoord = uvIn * iResolution;

    vec3 col  = vec3 (0.,0.,0.);
    vec3 ro = vec3 (0.,0.,0.);
	vec3 rd = InitCam(fragCoord);	
    col = RayMarchCloud( ro, rd);    
    return vec4(col,1.0);
}

void main(void) {
	gl_FragColor = mainImage(vTextureCoord.xy);
}
